
#include "hid.h"




void GetBuffer(uint8_t** org, uint8_t* rest, uint8_t len, uint8_t* buf){
    uint8_t cntBit = 8;
    *buf = 0;
    while (--len){
        *buf >>= 1;
        if ((**org) & 0x01){
            *buf |= 0x90;
        }

        if (!--(*rest)){
            *rest = 8;
            *org++;
        }

        if (!--cntBit){
            cntBit = 8;
            buf++;
            *buf = 0;
        }
    }
}




/*******************************************************************************
* Function Name  : hid_init
* Description    : 根据报表描述符初始化HID设备
* Input          : DataBuf  :
*                  nLen
* Output         : None
* Return         : None
*******************************************************************************/
void hid_init( uint8_t* DataBuf, uint8_t nLen )
{
    uint8_t i,j;
    uint8_t  iTag, iType , iSize;

    ThisUsbDev.reportID = 0;

    // 解析报表描述符
    for ( i = 0; i < nLen; ){
        iTag = (DataBuf[i] >> 4)& 0x0F ;
        iType = (DataBuf[i] >> 2) & 0x03 ;
        iSize = DataBuf[i] & 0x03;

#if DE_PRINTF
        printf("\t");
        for ( j = 0; j <= iSize; j++ ){
		    printf( "x%02X ", (UINT16)( DataBuf[i + j] ) );
	    }
        printf("\t\tx%02X ,x%02X ,x%02X ", (UINT16) iTag , iType, iSize);
        printf("\t");
        switch(DataBuf[i] & 0xfC){
        case 0b10000000:
            printf("input,main: ");
            break;
        case 0b10010000:
            printf("output,main: ");
            break;
        case 0b10110000:
            printf("feature,main: ");
            break;    
        case 0b10100000:
            printf("collection,main: ");
            break;
        case 0b11000000:
            printf("end collection,main: ");
            break;
        case 0b00000100:
            printf("usage page, global: ");
            break;
        case 0b00010100:
            printf("logical min,global: ");
            break;
        case 0b00100100:
            printf("logical max,global: ");
            break;
        case 0b00110100:
            printf("physical min,global: ");
            break;
        case 0b01000100:
            printf("physical max,global: ");
            break;
        case 0b01010100:
            printf("unit exponent,global: ");
            break;
        case 0b01100100:
            printf("unit,global: ");
            break;
        case 0b01110100:
            printf("report size,global: ");
            break;
        case 0b10000100:
            printf("report id,global: ");
            break;
        case 0b10010100:
            printf("report count,global: ");
            break;
        case 0b10100100:
            printf("push,global: ");
            break;
        case 0b10110100:
            printf("pop,global: ");
            break;
        case 0b00001000:
            printf("usage,local: ");
            break;
        case 0b00011000:
            printf("usage min,local: ");
            break;
        case 0b00101000:
            printf("usage max,local: ");
            break;
        case 0b00111000:
            printf("designator index,local: ");
            break;
        case 0b01001000:
            printf("designator min,local: ");
            break;
        case 0b01011000:
            printf("designator max,local: ");
            break;
        case 0b01111000:
            printf("string index,local: ");
            break;
        case 0b10001000:
            printf("string min,local: ");
            break;
        case 0b10011000:
            printf("string max,local: ");
            break;
        case 0b10101000:
            printf("delimiter,local: ");
            break;
        }
         printf("\n");
#endif	

		i += (1 + iSize);
	}

}



void hid_AnalyzeInData( uint8_t* DataBuf, uint8_t nLen )
{
    uint8_t i;
    uint8_t c, idx;
    signed char sc;
    
#if DE_PRINTF	
    if ( nLen )
    {
        for ( i = 0; i < nLen; i ++ )
        {
            // 读到的InData
            printf( "x%02X", DataBuf[i]);
        }
        printf( "\n");
    }
#endif

    if (ThisUsbDev.DeviceType == DEV_TYPE_KEYBOARD){

        memset(PS2_KB_INFO.KeyStatusTmp, 0, sizeof (PS2_KB_INFO.KeyStatusTmp));
        PS2_KB_INFO.KeyRepeat = 0;

        // 解析USB键盘数据
        // 暂时按8字节解析
        // 特殊按键
        c = DataBuf[0];
        if (c & 0x01) {
            // L Ctrl
            idx =usb_to_ps2_index_sp(0);
            PS2_KB_INFO.KeyStatusTmp[idx] = 1;
        }
        if (c & 0x02) {
            // L shift
            idx =usb_to_ps2_index_sp(1);
            PS2_KB_INFO.KeyStatusTmp[idx] = 1;
        }
        if (c & 0x04) {
            // L Atl
            idx =usb_to_ps2_index_sp(2);
            PS2_KB_INFO.KeyStatusTmp[idx] = 1;
        }
        if (c & 0x08) {
            // L Win
            idx =usb_to_ps2_index_sp(3);
            PS2_KB_INFO.KeyStatusTmp[idx] = 1;
        }
        if (c & 0x10) {
            // R Ctrl
            idx =usb_to_ps2_index_sp(4);
            PS2_KB_INFO.KeyStatusTmp[idx] = 1;
        }
        if (c & 0x20) {
            // R shift
            idx =usb_to_ps2_index_sp(5);
            PS2_KB_INFO.KeyStatusTmp[idx] = 1;
        }
        if (c & 0x40) {
            // R Alt
            idx =usb_to_ps2_index_sp(6);
            PS2_KB_INFO.KeyStatusTmp[idx] = 1;
        }
        if (c & 0x80) {
            // R Win
            idx =usb_to_ps2_index_sp(7);
            PS2_KB_INFO.KeyStatusTmp[idx] = 1;
        }

        // 普通按键
        for (i=2;i<8;i++){
            idx =usb_to_ps2_index(DataBuf[i]);
            if (idx){
                PS2_KB_INFO.KeyStatusTmp[idx] = 1;

                if (!PS2_KB_INFO.KeyStatus[idx]){
                    // 机打按键
                    PS2_KB_INFO.KeyRepeat = idx;
                    PS2_KB_INFO.KeyRepeatRateCnt = PS2_KB_INFO.KeyRepeatRate;   // 机打频率计数
                    PS2_KB_INFO.KeyDelayCnt = PS2_KB_INFO.KeyDelay;        // 机打延时计数
                }
            }
        }
    } else if (ThisUsbDev.DeviceType == DEV_TYPE_MOUSE){
        // 解析USB鼠标数据
        // 暂时按4字节解析
        c = DataBuf[0];
        
        // 鼠标左键
        if (c & 0x01) {
            PS2_MS_INFO.KeyStatusTmp[0] = 1;
        } else {
            PS2_MS_INFO.KeyStatusTmp[0] = 0;
        }

        // 鼠标右键
        if (c & 0x02) {
            PS2_MS_INFO.KeyStatusTmp[1] = 1;
        } else {
            PS2_MS_INFO.KeyStatusTmp[1] = 0;
        }
        
        // 鼠标中键
        if (c & 0x04) {
            PS2_MS_INFO.KeyStatusTmp[2] = 1;
        } else {
            PS2_MS_INFO.KeyStatusTmp[2] = 0;
        }

        // 鼠标键4
        if (c & 0x08) {
            PS2_MS_INFO.KeyStatusTmp[3] = 1;
        } else {
            PS2_MS_INFO.KeyStatusTmp[3] = 0;
        }

        // 鼠标键5
        if (c & 0x10) {
            PS2_MS_INFO.KeyStatusTmp[4] = 1;
        } else {
            PS2_MS_INFO.KeyStatusTmp[4] = 0;
        }

        // 左右位移
        sc = DataBuf[1];
        PS2_MS_INFO.Position[0] += sc;

        // 上下位移
        sc = DataBuf[2];
        PS2_MS_INFO.Position[1] += sc;
        
        // 滚轮
        sc = DataBuf[3];
        PS2_MS_INFO.Position[2] += sc;
    }
}


/*******************************************************************************
* Function Name  : hid_setup
* Description    : 通过发送指令设置HID设备
* Input          : attrib  :要设置的属性
*                           1:LED
*                  value   :要设置的值
* Output         : None
* Return         : None
*******************************************************************************/
void hid_setup( uint8_t attrib, uint8_t value )        // 设置HID设备
{
    if (ThisUsbDev.DeviceStatus != ROOT_DEV_SUCCESS){
        return;
    }
    switch(attrib){
        case 1:
            // 设置LED
            setOnOffLED(value);
            break;
    }

}